#!/usr/bin/perl
use strict;
use warnings;

# called from gitolite before any git operations are run

# "we", "our repo"  =>  the partial copy
# "main", "pco"     =>  the one which we are a "partial copy of"

my $main=`git config --file $ENV{GL_REPO_BASE_ABS}/$ENV{GL_REPO}.git/config --get gitolite.partialCopyOf`;
chomp ($main);

exit 0 unless $main;

die "ENV GL_RC not set\n" unless $ENV{GL_RC};
die "ENV GL_BINDIR not set\n" unless $ENV{GL_BINDIR};

unshift @INC, $ENV{GL_BINDIR};
require gitolite or die "parse gitolite.pm failed\n";
gitolite->import;

# go to the main repo.  Find a list of all the refs it has, and for each one,
# check if this user is allowed to read that ref from our repo.  If he is, add
# it to a list.

my %allowed;
wrap_chdir("$ENV{GL_REPO_BASE_ABS}/$main.git");
for my $ref (`git for-each-ref refs/heads '--format=%(refname)'`) {
    chomp($ref);
    my $ret = check_access($ENV{GL_REPO}, $ref, 'R', 1);
    $allowed{$ref} = 1 unless $ret =~ /DENIED/;
}

# now go to our repo and...
wrap_chdir("$ENV{GL_REPO_BASE_ABS}/$ENV{GL_REPO}.git");

# delete all existing refs that are not "allowed" (e.g., refs that were
# previously allowed but now are not, due to config file/rules change)
for my $ref (`git for-each-ref refs '--format=%(refname)'`) {
    chomp($ref);
    next if $allowed{$ref};
    system("git", "update-ref", "-d", $ref);
}

# now copy all allowed branches (and their tags, implicitly)
for my $ref (sort keys %allowed) {
    system("git", "fetch", "-f", "$ENV{GL_REPO_BASE_ABS}/$main.git", "$ref:$ref");
}

# now allow the git operation to proceed
exit 0
